package com.timothy.android;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * com Server
 * 
 * @author Aina.huang E-mail: 674023920@qq.com
 * @version 创建时间：2010 Jul 14, 2010 10:45:35 AM 类说明
 */
public class Server {
	
	private Map<String, String> baseStations;
	private Map<String, Integer> phoneAddress = new HashMap<String, Integer>();
	
	private static final int PORT = 9999;// 端口监听
	private ServerSocket server = null;
	private ExecutorService mExecutorService = null;// 线程池
	
	private static final String COMMAND_START = "<Message";
	private static final String COMMAND_END = "</Message>";
	
	public Server() {
		mExecutorService = Executors.newCachedThreadPool();// 创建一个线程池	
	}

	public void start(){
		try {
			server = new ServerSocket(PORT);
			System.out.println("Server Start...");
			System.out.println("IP:"+getLocalIP());
			Socket socket = null;
			while (true) {
				socket = server.accept();
				mExecutorService.execute( new Service(socket) );// 开启一个客户端线程.
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	
    public String getLocalIP(){
		InetAddress addr = null;
		try {
			addr = InetAddress.getLocalHost();
		} catch (UnknownHostException e) {
			System.out.println("IP not exists");
			e.printStackTrace();
		}
		return addr.getHostAddress();
    }
	
	public Map<String, Integer> getPhones(){
		return phoneAddress;
	}
	
	public Map<String, String> getBaseStations() {
		return baseStations;
	}

	public void setBaseStations(Map<String, String> baseStations) {
		this.baseStations = baseStations;
	}



	public class Service implements Runnable {

		private Socket socket;
		private BufferedReader in = null;

		public Service(Socket socket) {
			this.socket = socket;
			try {
				in = new BufferedReader( new InputStreamReader(socket.getInputStream()));
				String msg = "user:" + this.socket.getInetAddress();
				System.out.println(msg);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		public void run() {
			try {
				StringBuffer commond = new StringBuffer();
				while (true) {
					String msg = in.readLine();
					if ( msg != null ) {
						msg = msg.trim();
						if( msg.startsWith( COMMAND_START ) ) {
							commond.setLength(0);
							commond.append( msg );
						} else if( COMMAND_END.equalsIgnoreCase(msg) ){
							commond.append( msg );
							break;
						} else {
							commond.append( msg );
						}	
					} else {
						break;
					}
				}
				in.close();
				socket.close();
				
				processCommand( commond.toString() );
				
			} catch (Exception ex) {
				System.out.println("server 读取数据异常");
				ex.printStackTrace();
			}
		}

		private void processCommand(String command){
			System.out.println(command);
		    String type = XMLUtil.getPropertyValue(command, "Type");
			if( "GetBaseStations".equals( type ) ) {
				String head = XMLUtil.getChildren(command).get(0);
				String phone = XMLUtil.getChildren(head).get(0);
				String ip = XMLUtil.getPropertyValue( phone, "IPAddress");
				String port = XMLUtil.getPropertyValue( phone, "Port");
				
				phoneAddress.put(ip, Integer.valueOf(port));
			} else if ( "Authorize".equals( type ) ) {
				String head = XMLUtil.getChildren(command).get(0);
				String phone = XMLUtil.getChildren(head).get(0);
				String ip = XMLUtil.getPropertyValue( phone, "IPAddress");
				String port = XMLUtil.getPropertyValue( phone, "Port");
				
				String content = XMLUtil.getChildren(command).get(1);
				String bs = XMLUtil.getElementValue( XMLUtil.getChildren( content ).get(0) );
				String password = XMLUtil.getElementValue( XMLUtil.getChildren( content ).get(1) );
				
				if( baseStations.get( bs ).equals( password ) ) {
					sendSuccessMessage( ip, port );
				} else {
					sendFailureMessage( ip, port );
				}
			}	
		}
	}
	
	public void sendSuccessMessage(String ip, String port){
		String message =  "<Message Type=\"ConnectBase\">"+
							"<Content>" +
	      						"<Value>successfully</Value>" +
	    					"</Content>" +
						   "</Message>";
		MessageSender.PC_IP = ip;
    	MessageSender.PC_PORT = Integer.valueOf( port );
    	MessageSender.sendMessage( message );
	}
	
	public void sendFailureMessage(String ip, String port){
		String message =  "<Message Type=\"ConnectBase\">"+
							"<Content>" +
									"<Value>failed</Value>" +
							"</Content>" +
						   "</Message>";
		MessageSender.PC_IP = ip;
		MessageSender.PC_PORT = Integer.valueOf( port );
		MessageSender.sendMessage( message );
	}
	
	public void sendBaseStations2Phones(Set<String> baseStations){
		String message = "<Message Type=\"BaseStations\">"+
	    				 "<Content>";
		for( String bs : baseStations )
			message = message +	"<BaseStation Name=\""+bs +"\"/>";
	    message = message +
	    		         "</Content>" +
	    		         "</Message>";
	    
	    for( Map.Entry<String, Integer> e : phoneAddress.entrySet() ) {
	    	MessageSender.PC_IP = e.getKey();
	    	MessageSender.PC_PORT = e.getValue();
	    	MessageSender.sendMessage( message );
	    }
	}
	
	public void sendMessage( String message ) {
		for( Map.Entry<String, Integer> e : phoneAddress.entrySet() ) {
	    	MessageSender.PC_IP = e.getKey();
	    	MessageSender.PC_PORT = e.getValue();
	    	MessageSender.sendMessage( message );
	    }
	}
}